from rest_framework import serializers
from .models import User,Address
import re
from django_redis import get_redis_connection
from celery_tasks.email.tasks import email_active_send
from goods.models import SKU
from rest_framework_jwt.settings import api_settings
from django_redis import get_redis_connection



class UserRegisterSerializer(serializers.Serializer):



    #不使用ModelSerializer的原因：
    #1.多个参数不存在
    #2.密码需要加密，没法实现
    #当前是注册逻辑，只考虑饭序列化不考虑序列化
    username = serializers.CharField(
        max_length=20,
        min_length=5,
        error_messages={
            'max_length':'请输入5-20个字符的用户名',
            'min_length':'请输入5-20个字符的用户名'
        },
    )

    password=serializers.CharField(
        min_length=8,
        max_length=20,
        error_messages={
            'min_length':'密码最少8位，最长20位',
            'max_length': '密码最少8位，最长20位'
        },
        write_only=True
    )
    password2=serializers.CharField(write_only=True)

    sms_code=serializers.IntegerField(write_only=True)

    mobile=serializers.CharField()

    allow=serializers.BooleanField(write_only=True)

    def validate_username(self,value):
        if User.objects.filter(username=value).count()>0:
            raise serializers.ValidationError('用户名已经存在')
        return value

    def validate_mobile(self,value):
        #验证手机号格式是否正确
        if not re.match(r'^1[3-9]\d{9}$',value):
            raise serializers.ValidationError('手机号格式错误')
        #判断手机号是否已经使用
        if User.objects.filter(mobile=value).count()>0:
            raise serializers.ValidationError('手机号已经被使用')
        return value
    def validate_allow(self,value):
        if not value:
            raise serializers.ValidationError('必须同意协议')
        return value

    def validate(self, attrs):
        #验证两个个密码是否一直
        password1=attrs.get('password')
        password2=attrs.get('password2')
        if password1!=password2:
            raise serializers.ValidationError('两个密码不一致')

        # 判断短信吗是否正确
        mobile=attrs.get('mobile')
        sms_code=attrs.get('sms_code')
        redis_cli=get_redis_connection('sms')
        # 1.聪redis中毒去，
        sms_code_redis=redis_cli.get('sms_'+mobile)
        # 2.判断是否国企
        if sms_code_redis is None:
            raise serializers.ValidationError('短信验证码已经过期')
        # 2.判断两个验证码是否一致
        if sms_code != int(sms_code_redis):
            raise serializers.ValidationError('短信验证码错误')
        return attrs

    token = serializers.CharField(label='登录状态token', read_only=True)

    def create(self, validated_data):
        #validated_data满足验证的请求数据
        #1.聪字典中获取数据
        username = validated_data.get('username')
        password = validated_data.get('password')
        mobile = validated_data.get('mobile')
        # 2. 创建对象并保存
        user = User()
        user.username = username
        #直接保存密码，未加密
        #user.password = password
        #加密
        user.set_password(password)
        user.mobile = mobile
        user.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        return user
        # return {
        #     'id':user.id,
        #     'username':username,
        #     'mobile':mobile,
        # }



class UserSerializer(serializers.ModelSerializer):
    """
    用户详细信息序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')




class UserEmailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id','email']

        #默认update修改所有的属性，所以需要修改，只修改email属性
    def update(self, instance, validated_data):
        email=validated_data.get('email')
        instance.email = email
        instance.save()

        #发邮件，调用方法，向邮件服务器发消息，耗时，写道celery中
        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + instance.email_dumps()

        email_active_send.delay(email,verify_url)
        return instance


class AddressSerializer(serializers.ModelSerializer):
    #省市区关系属性的输出字符串
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    #添加，修改时，需要为id属性赋值
    province_id = serializers.IntegerField(write_only=True)
    city_id = serializers.IntegerField(write_only=True)
    district_id = serializers.IntegerField(write_only=True)
    class Meta:
        model = Address
        # fields = '__all__'
        exclude=['is_deleted','user']

    #创建
    def create(self, validated_data):
        #创建收获地址是，需要指定用户，而这个值不是客户端传递的，应该聪当前登录的用户读取
        validated_data['user_id']=self.context['request'].user.id
        return super().create(validated_data)


class TitleSerializer(serializers.ModelSerializer):
    class Meta:
        model=Address
        fields=['id','title']



class HistorySerializer(serializers.Serializer):
    sku_id = serializers.IntegerField(min_value=1)

    def validate_sku_id(self,value):
        if SKU.objects.filter(pk=value).count()<0:
            raise serializers.ValidationError('商品编号无效')
        return value

    def create(self, validated_data):
        sku_id=validated_data.get('sku_id')
        #存入redis
        redis_cli=get_redis_connection('history')
        key='history_%d'%self.context['request'].user.id
        #1.删除此sku_id
        redis_cli.lrem(key,0,sku_id)
        #2.添加
        redis_cli.lpush(key,sku_id)
        #3.控制5个元素
        redis_cli.ltrim(key,0,4)

        return {'sku_id':sku_id}